在使用 gin
开发接口的时候,返回接口数据是这样写的。
type response struct {Code int `json:"code"`Msg string `json:"msg"`Data interface{} `json:"data"`}// always return http.StatusOKc.JSON(http.StatusOK, response{Code: 20101,Msg: "用户手机号不合法",Data: nil,})
这种写法 code
、msg
都是在哪需要返回在哪定义,没有进行统一管理。
// 比如,返回“用户手机号不合法”错误c.JSON(http.StatusOK, errno.ErrUserPhone.WithID(c.GetString("trace-id")))// 正确返回c.JSON(http.StatusOK, errno.OK.WithData(data).WithID(c.GetString("trace-id")))
errno.ErrUserPhone
、errno.OK
表示自定义的错误码,下面会看到定义的地方。
.WithID()
设置当前请求的唯一ID,也可以理解为链路ID,忽略也可以。
.WithData()
设置成功时返回的数据。
下面分享下编写的 errno
包源码,非常简单,希望大家不要介意。
// errno/errno.gopackage errnoimport ("encoding/json")var _ Error = (*err)(nil)type Error interface {// i 为了避免被其他包实现i()// WithData 设置成功时返回的数据WithData(data interface{}) Error// WithID 设置当前请求的唯一IDWithID(id string) Error// ToString 返回 JSON 格式的错误详情ToString() string}type err struct {Code int `json:"code"` // 业务编码Msg string `json:"msg"` // 错误描述Data interface{} `json:"data"` // 成功时返回的数据ID string `json:"id,omitempty"` // 当前请求的唯一ID,便于问题定位,忽略也可以}func NewError(code int, msg string) Error {return &err{Code: code,Msg: msg,Data: nil,}}func (e *err) i() {}func (e *err) WithData(data interface{}) Error {e.Data = datareturn e}func (e *err) WithID(id string) Error {e.ID = idreturn e}// ToString 返回 JSON 格式的错误详情func (e *err) ToString() string {err := &struct {Code int `json:"code"`Msg string `json:"msg"`Data interface{} `json:"data"`ID string `json:"id,omitempty"`}{Code: e.Code,Msg: e.Msg,Data: e.Data,ID: e.ID,}raw, _ := json.Marshal(err)return string(raw)}
// errno/code.gopackage errnovar (// OKOK = NewError(0, "OK")// 服务级错误码ErrServer = NewError(10001, "服务异常,请联系管理员")ErrParam = NewError(10002, "参数有误")ErrSignParam = NewError(10003, "签名参数有误")// 模块级错误码 - 用户模块ErrUserPhone = NewError(20101, "用户手机号不合法")ErrUserCaptcha = NewError(20102, "用户验证码有误")// ...)
code.go
文件中定义。1 | 01 | 01 |
---|---|---|
服务级错误码 | 模块级错误码 | 具体错误码 |